//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<ISlotLayout.h>
///	@path	~/src/graphics/
///	@date	2007/10/26
///	@desc	Vertex slot layout.

#pragma once

#include "xeres.h"

#include "object/IObject.h"

#include "graphics/DxHelpers.h"
#include "graphics/IDevice.h"

namespace xeres {

	/*! 
		\enum	VertexSlotType
		\brief
	*/
	enum VertexSlotType
	{
		VertexSlotType_Float1		= 0,
		VertexSlotType_Float2		= 1,
		VertexSlotType_Float3		= 2,
		VertexSlotType_Float4		= 3,
		VertexSlotType_Byte4		= 4,
		VertexSlotType_Byte4Norm	= 5,
		VertexSlotType_Short2		= 6,
		VertexSlotType_Short2Norm	= 7,
		VertexSlotType_Short4		= 8,
		VertexSlotType_Short4Norm	= 9,
		VertexSlotType_UShort2Norm	= 10,
		VertexSlotType_UShort4Norm	= 11,
		VertexSlotType_Half2		= 12,
		VertexSlotType_Half4		= 13,
		//
		VertexSlotType_ColorRGBA	= 14,
		VertexSlotType_ColorfRGBA	= 15,
		//
		VertexSlotType_last
	};

	/*! 
		\struct	VertexSlotDeclaration
		\brief
	*/
	struct VertexSlotDeclaration
	{
		uint			offset;		// vertex offset
		uint			slot;		// vertex slot
		VertexSlotType	type;		// vertex format
		const char *	semantic;	// vertex semantic

		/// \ctor
		VertexSlotDeclaration( void ) : offset( -1 ) , slot( -1 ) , type( VertexSlotType_last ) , semantic( NULL ) {}

		/// \ctor
		VertexSlotDeclaration( const VertexSlotDeclaration& rhs )
			: offset( rhs.offset ) , slot( rhs.slot ) , type( rhs.type ) , semantic( rhs.semantic )
		{}

		/// \ctor
		VertexSlotDeclaration( uint offset , uint slot , VertexSlotType type , const char * semantic )
			: offset( offset ) , slot( slot ) , type( type ) , semantic( semantic )
		{}

		/// \brief	Make slot declaration to string.
		AString to_str( void ) const;

		/// \brief	Make slot signature. Notice decls must be sorted.
		static AString make_signature( const std::vector<VertexSlotDeclaration>& decls );

		// for sorting declaration list.
		struct SortDecl
		{
			bool operator () ( const VertexSlotDeclaration& left , const VertexSlotDeclaration& right ) const
			{
				if( left.slot == right.slot )
					return left.offset < right.offset;
				return left.slot < right.slot;
			}
		};
	};

	/*!
		\class	ISlotLayout
		\brief
	*/
	class ISlotLayout : public IObject
	{
	public:

		/// \ctor
		ISlotLayout( void );

		/// \dtor
		virtual ~ISlotLayout( void );

		DECL_IOBJECT_INTERFACE( ISlotLayout , IObject );

	public:

		// interface

		/*!
			\brief		Get layout size.
		*/
		virtual size_t GetLayoutSize( void ) = 0;

		/*! 
			\brief		Expand source data to mapped output vertex buffer.
		*/
		virtual bool ExpandData( uint index , const byte * input , size_t input_size , byte * output ) = 0;

		/*! 
			\brief		Stream source data to mapped output vertex buffer.
		*/
		virtual bool StreamData( const byte * input , size_t stride , size_t count , byte * output ) = 0;
	};

} // namespace xeres
